package com.wangsd.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

public class DateUtils {

    private static final String LOCK_SEQ = "LOCK_SEQ";

    /**
     * 获取带毫秒的字符串
     * @return
     */
    public static String getCurDateTimeSSS() {
        synchronized (LOCK_SEQ) {
            return formatDate(new Date(), "yyyyMMddHHmmssSSS");
        }
    }
    /**
     * 将指定Date类型转换成指定格式的字符串 yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    /**
     * 将指定Date类型转换成指定格式的字符串yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @return
     */
    public static String formatDatetime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 将指定Date类型转换成指定格式的字符串,格式串参见类注释
     *
     * @param date   日期方式
     * @param format 指定的格式,当format为NULL或空串时,<BR>
     *               默认为 yyyy-MM-dd 格式
     * @return 当date为NULL时, 返回空串
     */
    public static String formatDate(Date date, String format) {

        String dtstr = "";
        if (date == null) {
            return dtstr;
        }

        if (format == null || "".equals(format.trim())) {
            format = "yyyy-MM-dd";
        }

        SimpleDateFormat sdf = new SimpleDateFormat(format);
        dtstr = sdf.format(date);
        return (dtstr == null ? "" : dtstr);

    }

    /**
     * 将指定字串转换按指定格式转换成java.util.Date类型
     *
     * @param dateStr 日期字串 yyyy-MM-dd 格式
     * @return 当dateStr 为null或者转换出错时,返回NULL值
     * @throws RuntimeException 日期格式与格式串不一致时，抛出RuntimeException
     */
    public static Date parseDate(String dateStr) {
        return parseDate(dateStr, "yyyy-MM-dd");
    }

    /**
     * 将指定字串转换按指定格式转换成java.util.Date类型
     *
     * @param dateStr 日期字串 yyyy-MM-dd HH:mm:ss 格式
     * @return 当dateStr 为null或者转换出错时,返回NULL值
     * @throws RuntimeException 日期格式与格式串不一致时，抛出RuntimeException
     */
    public static Date paseDatetime(String dateStr) {
        return parseDate(dateStr, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 将指定字串转换按指定格式转换成java.util.Date类型
     *
     * @param dateStr 日期字串
     * @param format  指定的格式,当format为NULL或空串时,<BR>
     *                默认为 yyyy-MM-dd 格式
     * @return 当dateStr 为null或者转换出错时,返回NULL值
     * @throws RuntimeException 日期格式与格式串不一致时，抛出RuntimeException
     */
    public static Date parseDate(String dateStr, String format) {
        Date date = null;
        if (dateStr == null || "".equals(dateStr.trim())) {
            return new Date();
        }
        if (format == null || "".equals(format.trim())) {
            format = "yyyy-MM-dd";
        }

        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException ex) {
            throw new RuntimeException("日期格式与格式串不一致", ex);
        }

        return date;
    }


    /**
     * 获取当前时间日历对象
     *
     * @return 返回java.util.Calendar日期对象
     */
    public static Calendar getCurCalendar() {
        return Calendar.getInstance();
    }

    /**
     * 将指定时间串转换成日期时间对象
     *
     * @param dateStr 时间串,可以是yyyy-MM-dd格式 或者 yyyy-MM-dd HH:mm:ss 格式
     * @return 返回指定时间的Calendar对象
     * @throws NullPointerException 当日期时间格式不正确时
     */
    public static Calendar parseCalendar(String dateStr) {
        Date dt = null;
        dt = parseDate(dateStr, "yyyy-MM-dd HH:mm:ss");
        if (dt == null) {
            dt = parseDate(dateStr);
        }
        Calendar c = getCurCalendar();
        c.setTime(dt);
        return (c);
    }

    /**
     * @return 相差时差
     * @see #dateDiff(Calendar, Calendar, byte)
     */
    public static long dateDiff(String dateFrom, String dateTo, int unit) {
        Calendar from = parseCalendar(dateFrom);
        Calendar to = parseCalendar(dateTo);
        return dateDiff(from, to, unit);
    }

    /**
     * @param dateFrom 开始时间
     * @param dateTo   结束时间
     * @param unit     单位
     * @return
     * @see #dateDiff(Calendar, Calendar, byte)
     */
    public static long dateDiff(Date dateFrom, Date dateTo, int unit) {
        Calendar from = Calendar.getInstance();
        from.setTime(dateFrom);
        Calendar to = Calendar.getInstance();
        to.setTime(dateTo);
        return dateDiff(from, to, unit);
    }

    /**
     * 返回2个日期之间的差距 unit是时间计算的单位,为本类常量DIFF_&lgt;XXXX&rgt;中的任一类型
     *
     * @param dateFrom 开始时间的时间串,可以是yyyy-MM-dd格式 或者 yyyy-MM-dd HH:mm:ss 格式
     * @param dateTo   结束时间的时间串,可以是yyyy-MM-dd格式 或者 yyyy-MM-dd HH:mm:ss 格式
     * @param unit     是时间计算的单位,为以下值中的任一值:<br>
     *                 0 以年为单位<br>
     *                 1 以月为单位<br>
     *                 2 以日为单位<br>
     *                 3 以小时为单位<br>
     *                 4 以分钟为单位<br>
     *                 5 以秒为单位<br>
     *                 6 以毫秒为单位
     * @return 相差时差
     */
    @SuppressWarnings("static-access")
    public static long dateDiff(Calendar dateFrom, Calendar dateTo, int unit) {
        long diff = dateTo.getTimeInMillis() - dateFrom.getTimeInMillis();
        long interval = 0;
        switch (unit) {
            case 0: {
                Calendar from = dateFrom;
                Calendar to = dateTo;
                interval = to.get(to.YEAR) - from.get(from.YEAR);
                from.set(from.YEAR, to.get(to.YEAR));
                if (from.after(to)) {
                    if (interval < 0) {
                        interval++;
                    } else {
                        interval--;
                    }
                }
                break;
            }
            case 1: {
                int year = dateTo.get(dateTo.YEAR) - dateFrom.get(dateFrom.YEAR);
                int month = dateTo.get(dateTo.MONTH) - dateFrom.get(dateFrom.MONTH);
                Calendar from = dateFrom;
                Calendar to = dateTo;
                from.set(from.YEAR, dateTo.get(dateTo.YEAR));
                from.set(from.MONTH, dateTo.get(dateTo.MONTH));
                interval = year * 12 + month;
                if (from.after(to)) {
                    if (interval < 0) {
                        interval++;
                    } else {
                        interval--;
                    }
                }
                break;
            }
            case 2:
                interval = (int) (diff / (1000 * 60 * 60 * 24));
                break;
            case 3:
                interval = (int) (diff / (1000 * 60 * 60));
                break;
            case 4:
                interval = (int) (diff / (1000 * 60));
                break;
            case 5:
                interval = (int) (diff / 1000);
                break;
            default:
                interval = diff;
        }
        return interval;
    }


    public static void main(String[] args) {
        //        String str = "2020-02-21 10:00:00";
//        Date date = new Date();
//        System.out.println(DateUtils.dateDiff(DateUtils.parseDate(str, "yyyy-MM-dd HH:mm:ss"), date, 6));
//        System.out.println(DateUtils.formatDate(DateUtils.paseDatetime("2020-04-16 23:59:59"), "yyyy-MM-dd'T'HH:mm:ss.SSS"));
        String str = "2020-02-18T22:05:12+08:00";
        System.out.println(DateUtils.formatDate(DateUtils.parseDate(str, "yyyy-MM-dd'T'HH:mm:ss"),"yyyy-MM-dd HH:mm:ss"));
        LocalDateTime localDateTime = LocalDateTime.now();
        String s1 = localDateTime.format(DateTimeFormatter.BASIC_ISO_DATE);
        String s2 = localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(s1);
        System.out.println(s2);
        String a = "2018-10-10T16:20:35+00:00";
        LocalDateTime date = LocalDateTime.parse(a, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        String dateString = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println("dateString:"+dateString);
    }

}
